#ifndef _creazy_vector_
#define _creazy_vector_

#include <algorithm>

template <typename T>
class Vector
{
private:
    int Size;
    int Capacity;
    T *elements;                            

public:
    explicit Vector(int initSize =0):Size{initSize},Capacity{initSize + SPARE_CAPACITY}  //向量的构造函数，设定当向量元素个数和向量的总容量并分配空间
    {elements = new T[Capacity];}

    explicit Vector(int initSize,int spare_capacity):Size{initSize},Capacity{initSize + spare_capacity}  //向量的构造函数，设定当向量元素个数和向量的总容量并分配空间
    {elements = new T[Capacity];}

    Vector(const Vector& rhs):Size{rhs.Size},Capacity{rhs.Capacity},elements{NULL}       //提供一个向量参数的构造函数，创建一个新的向量并将目标向量拷贝到新向量中。
    {
        elements = new T [Capacity];
        for(int i = 0; i< Size; i++)
            elements[i] = rhs.elements[i];
    }

    Vector & operator = (const Vector & rhs)                //对“=”的重载，将目标向量拷贝到新的向量之中。
    {
        Vector copy = rhs;
        std::swap(*this, copy);
        return *this;
    }

    ~Vector()                       //析构函数，将分配的地址空间进行释放。
    {delete [] elements;}

    Vector(Vector && rhs):Size{rhs.Size},Capacity{rhs.Capacity},elements{rhs.elements}   //地址转换函数，将原地址的数据先拷贝给this指针，然后将原地址指针指向空。
    {
        rhs.elements = NULL;
        rhs.Size = 0;
        rhs.Capacity = 0;
    }

    Vector& operator = (Vector && rhs)              //使用swap函数进行地址指针交换到this指针中。
    {
        std::swap(Size, *rhs.Size);
        std::swap(Capacity, *rhs.Capacity);
        std::swap(elements,*rhs.elements);
        return *this;
    }

    void resize(int newSize)                        //对向量进行元素个数重设定，如果当前的容量小于目标元素个数，分配两倍于目标元素个数的容量。
    {
        if(newSize > Capacity)
            reserve(newSize*2);
        Size = newSize;
    }

    void reserve(int newCapacity)                   //分配新的容量，将原向量在不改变内容元素的前提下对向量进行扩充。
    {
        if(newCapacity < Size)
            return;
        T* newArray = new T [newCapacity];
        for(int i =0; i<Size;++i)
            newArray[i] = std::move(elements[i]);
        
        Capacity = newCapacity;
        std::swap(elements, newArray);
        delete[]newArray;
    }

    T &operator[](int index)                //重载[]对向量元素进行读取。
    {return elements[index];}

    const T & operator[](int index) const  
    {return elements[index];}

    bool empty()const                       //这些都太简单了不注释了。
      {return size() == 0;}
    int size()const
      {return Size;}
    int capacity()const
      {return Capacity;}

    void push_back(const T & x)         //两种方法进行类似入栈的操作。如果超过容量了，需要进行空间分配。
    {
        if(Size == Capacity)
            reserve(2*Capacity+1);
        elements[Size++] = x;
    }

    void push_back(T && x)
    {
        if(Size == Capacity)
            reserve(2*Capacity+1);
        elements[Size++] = std::move(*x);
    }

    void pop_back()                 //直接将size减一即可实现类似出栈操作。
    {
        --Size;
    }

    const T & back()const{return elements[Size - 1];}

    typedef T * iterator;
    typedef const T * const_iterator;

    iterator begin()
    {return &elements[0];}
    const_iterator begin() const
    {return &elements[0];}

    iterator end()
    {return &elements[size()];}

    const_iterator end() const
    {return &elements[size()];}

    static const int SPARE_CAPACITY = 16; 
};


#else
// do nothing;
#endif

